using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace BlockOS.Client
{
    public class Toast : MonoBehaviour
    {
        [SerializeField]
        private TMP_Text text;
        [SerializeField]
        private Graphic background;

        public float m_ShowAnimationTime;
        public float m_DefaultDuration;
        public float m_HideAnimationTime;
        public float m_Interval;

        private readonly Queue<(string, float)> queue = new();
        private bool coroutineRunning;

        public void Show(string message)
        {
            Show(message, m_DefaultDuration);
        }

        public void Show(string message, float duration)
        {
            Debug.Log($"Toasting: {message}");
            queue.Enqueue((message, duration));
            if (isActiveAndEnabled && !coroutineRunning)
            {
                StartCoroutine(CoShowToast());
            }
        }

        private IEnumerator CoShowToast()
        {
            Debug.Log($"Entered toast Coroutine, queue count: {queue.Count}");
            coroutineRunning = true;
            while (queue.Count > 0)
            {
                var (message, duration) = queue.Dequeue();
                Debug.Log($"Trying to show {message} with {duration}s.");
                text.text = message;

                background.gameObject.SetActive(true);
                yield return CoSetAlphaAnimation(m_ShowAnimationTime, ShowAnimation);
                yield return new WaitForSeconds(duration);
                yield return CoSetAlphaAnimation(m_HideAnimationTime, HideAnimation);
                background.gameObject.SetActive(false);
                yield return new WaitForSeconds(m_Interval);
            }
            coroutineRunning = false;
        }

        private IEnumerator CoSetAlphaAnimation(float duration, Func<float, float> getAlpha)
        {
            var time = 0.0f;
            while (time < duration)
            {
                var alpha = getAlpha(time / duration);
                var tColor = text.color;
                var bColor = background.color;

                tColor.a = bColor.a = alpha;

                text.color = tColor;
                background.color = bColor;
                yield return null;
                time += Time.deltaTime;
            }
        }

        private float ShowAnimation(float percent)
        {
            return Mathf.SmoothStep(0, 0.6f, percent);
        }

        private float HideAnimation(float percent)
        {
            return Mathf.SmoothStep(0.6f, 0, percent);
        }
    }
}
